package com.mathmodeling.controller;

import com.mathmodeling.dto.ApiResponse;
import com.mathmodeling.entity.Topic;
import com.mathmodeling.entity.Team;
import com.mathmodeling.entity.User;
import com.mathmodeling.entity.TeamMember;
import com.mathmodeling.repository.TopicRepository;
import com.mathmodeling.repository.TeamRepository;
import com.mathmodeling.repository.UserRepository;
import com.mathmodeling.repository.TeamMemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.UUID;
import java.util.ArrayList;
import com.mathmodeling.entity.Work;
import com.mathmodeling.repository.WorkRepository;

@RestController
@RequestMapping("/students")
public class StudentController {
    
    @Autowired
    private TopicRepository topicRepository;
    
    @Autowired
    private TeamRepository teamRepository;
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private TeamMemberRepository teamMemberRepository;
    
    @Autowired
    private WorkRepository workRepository;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Value("${file.upload.path}")
    private String uploadPath;
    
    @Value("${file.upload.topic}")
    private String topicPath;
    
    /**
     * 队伍注册 - 严格按照API文档
     */
    @PostMapping("/register")
    public ApiResponse<RegisterResponse> register(@RequestBody RegisterRequest request) {
        try {
            // 验证请求参数
            if (request.getCaptain() == null) {
                return ApiResponse.error(400, "队长信息不能为空");
            }
            
            if (request.getTeamName() == null || request.getTeamName().trim().isEmpty()) {
                return ApiResponse.error(400, "队伍名称不能为空");
            }
            
            // 验证队长信息
            CaptainRequest captain = request.getCaptain();
            if (captain.getUsername() == null || captain.getUsername().trim().isEmpty()) {
                return ApiResponse.error(400, "队长用户名不能为空");
            }
            if (captain.getPassword() == null || captain.getPassword().trim().isEmpty()) {
                return ApiResponse.error(400, "队长密码不能为空");
            }
            if (captain.getName() == null || captain.getName().trim().isEmpty()) {
                return ApiResponse.error(400, "队长姓名不能为空");
            }
            if (captain.getStudentId() == null || captain.getStudentId().trim().isEmpty()) {
                return ApiResponse.error(400, "队长学号不能为空");
            }
            if (captain.getPhone() == null || captain.getPhone().trim().isEmpty()) {
                return ApiResponse.error(400, "队长手机号不能为空");
            }
            
            // 验证队员信息
            if (request.getMembers() == null || request.getMembers().isEmpty()) {
                return ApiResponse.error(400, "至少需要1名队员");
            }
            
            if (request.getMembers().size() > 4) {
                return ApiResponse.error(400, "队员数量不能超过4人");
            }
            
            // 验证队员信息完整性
            for (MemberRequest member : request.getMembers()) {
                if (member.getName() == null || member.getName().trim().isEmpty()) {
                    return ApiResponse.error(400, "队员姓名不能为空");
                }
                if (member.getStudentId() == null || member.getStudentId().trim().isEmpty()) {
                    return ApiResponse.error(400, "队员学号不能为空");
                }
                if (member.getPhone() == null || member.getPhone().trim().isEmpty()) {
                    return ApiResponse.error(400, "队员手机号不能为空");
                }
            }
            
            // 检查队长用户名是否已存在
            if (userRepository.existsByUsername(captain.getUsername())) {
                return ApiResponse.error(400, "队长用户名已存在");
            }
            
            // 检查队长学号是否已存在
            if (userRepository.existsByStudentId(captain.getStudentId())) {
                return ApiResponse.error(400, "队长学号已存在");
            }
            
            // 检查队员学号是否已存在
            for (MemberRequest member : request.getMembers()) {
                if (userRepository.existsByStudentId(member.getStudentId()) || 
                    teamMemberRepository.existsByStudentId(member.getStudentId())) {
                    return ApiResponse.error(400, "队员学号 " + member.getStudentId() + " 已存在");
                }
            }
            
            // 检查队员学号是否与队长学号重复
            for (MemberRequest member : request.getMembers()) {
                if (member.getStudentId().equals(captain.getStudentId())) {
                    return ApiResponse.error(400, "队员学号不能与队长学号相同");
                }
            }
            
            // 检查队员学号之间是否重复
            for (int i = 0; i < request.getMembers().size(); i++) {
                for (int j = i + 1; j < request.getMembers().size(); j++) {
                    if (request.getMembers().get(i).getStudentId().equals(request.getMembers().get(j).getStudentId())) {
                        return ApiResponse.error(400, "队员学号不能重复");
                    }
                }
            }
            
            // 创建队长用户
            User captainUser = new User();
            captainUser.setId(UUID.randomUUID().toString());
            captainUser.setUsername(captain.getUsername());
            captainUser.setPassword(passwordEncoder.encode(captain.getPassword()));
            captainUser.setName(captain.getName());
            captainUser.setStudentId(captain.getStudentId());
            captainUser.setPhone(captain.getPhone());
            captainUser.setRole("student");
            
            userRepository.save(captainUser);
            
            // 创建团队
            Team team = new Team();
            team.setId(UUID.randomUUID().toString());
            team.setName(request.getTeamName());
            team.setCaptainId(captainUser.getId());
            
            // 设置队长信息
            captainUser.setTeamId(team.getId());
            userRepository.save(captainUser);
            
            // 添加队员信息到team_member表
            for (MemberRequest member : request.getMembers()) {
                TeamMember teamMember = new TeamMember();
                teamMember.setId(UUID.randomUUID().toString());
                teamMember.setTeamId(team.getId());
                teamMember.setName(member.getName());
                teamMember.setStudentId(member.getStudentId());
                teamMember.setPhone(member.getPhone());
                
                teamMemberRepository.save(teamMember);
            }
            
            teamRepository.save(team);
            
            RegisterResponse response = new RegisterResponse();
            response.setTeamId(team.getId());
            response.setUsername(captainUser.getUsername());
            
            return ApiResponse.success("注册成功", response);
            
        } catch (Exception e) {
            return ApiResponse.error(500, "注册失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取题目选择列表 - 严格按照API文档
     */
    @GetMapping("/topics")
    public ApiResponse<List<Topic>> getTopics(@RequestParam String contestId) {
        try {
            // 验证contestId参数
            if (contestId == null || contestId.trim().isEmpty()) {
                return ApiResponse.error(400, "竞赛ID不能为空");
            }
            
            List<Topic> topics = topicRepository.findByContestId(contestId);
            
            // 如果没有找到题目，返回空列表而不是错误
            if (topics == null) {
                topics = new ArrayList<>();
            }
            
            return ApiResponse.success("获取成功", topics);
        } catch (Exception e) {
            return ApiResponse.error(500, "获取题目列表失败: " + e.getMessage());
        }
    }
    
    /**
     * 下载竞赛题目文件 - 严格按照API文档路径
     */
    @GetMapping("/contests/{contestId}/topics/download")
    public ResponseEntity<Resource> downloadContestFile(@PathVariable String contestId) {
        try {
            // 验证contestId参数
            if (contestId == null || contestId.trim().isEmpty()) {
                return ResponseEntity.badRequest().build();
            }
            
            // 检查竞赛是否存在
            // 这里可以添加竞赛存在性验证逻辑
            
            // 构建文件路径 - 根据contestId获取题目文件
            Path filePath = Paths.get(uploadPath + topicPath + contestId + ".pdf");
            Resource resource = new UrlResource(filePath.toUri());
            
            // 检查文件是否存在且可读
            if (resource.exists() && resource.isReadable()) {
                // 获取文件名
                String filename = contestId + ".pdf";
                
                return ResponseEntity.ok()
                        .contentType(MediaType.APPLICATION_PDF)
                        .header(HttpHeaders.CONTENT_DISPOSITION, 
                                "attachment; filename=\"" + filename + "\"")
                        .header(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate")
                        .header(HttpHeaders.PRAGMA, "no-cache")
                        .header(HttpHeaders.EXPIRES, "0")
                        .body(resource);
            } else {
                // 文件不存在
                return ResponseEntity.notFound().build();
            }
        } catch (MalformedURLException e) {
            // URL格式错误
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            // 其他异常
            return ResponseEntity.internalServerError().build();
        }
    }
    
    /**
     * 上传作品和支撑材料 - 严格按照API文档响应格式
     */
    @PostMapping("/works/upload")
    public ApiResponse<UploadResponse> uploadWork(@RequestParam String contestId,
                                        @RequestParam String topicId,
                                        @RequestParam("thesis") MultipartFile thesis,
                                        @RequestParam("support") MultipartFile support) {
        try {
            // 验证必需参数
            if (contestId == null || contestId.trim().isEmpty()) {
                return ApiResponse.error(400, "竞赛ID不能为空");
            }
            
            if (topicId == null || topicId.trim().isEmpty()) {
                return ApiResponse.error(400, "题目ID不能为空");
            }
            
            if (thesis == null || thesis.isEmpty()) {
                return ApiResponse.error(400, "论文文件不能为空");
            }
            
            if (support == null || support.isEmpty()) {
                return ApiResponse.error(400, "支撑材料不能为空");
            }
            
            // 验证文件格式
            String thesisFileName = thesis.getOriginalFilename();
            String supportFileName = support.getOriginalFilename();
            
            if (thesisFileName == null || !thesisFileName.toLowerCase().endsWith(".pdf")) {
                return ApiResponse.error(400, "论文文件必须是PDF格式");
            }
            
            if (supportFileName == null || !supportFileName.toLowerCase().endsWith(".rar")) {
                return ApiResponse.error(400, "支撑材料必须是RAR格式");
            }
            
            // 验证文件大小（可选）
            if (thesis.getSize() > 50 * 1024 * 1024) { // 50MB
                return ApiResponse.error(400, "论文文件大小不能超过50MB");
            }
            
            if (support.getSize() > 100 * 1024 * 1024) { // 100MB
                return ApiResponse.error(400, "支撑材料大小不能超过100MB");
            }
            
            // 获取题目信息
            Topic topic = topicRepository.findById(topicId)
                    .orElseThrow(() -> new RuntimeException("题目不存在"));
            
            // 获取当前用户的团队信息
            // 这里需要从JWT token中获取用户信息，简化实现
            String currentUsername = "student1"; // 实际应该从JWT获取
            User currentUser = userRepository.findByUsername(currentUsername)
                    .orElseThrow(() -> new RuntimeException("用户不存在"));
            
            if (currentUser.getTeamId() == null) {
                return ApiResponse.error(400, "用户未加入团队");
            }
            
            // 获取团队信息
            Team team = teamRepository.findById(currentUser.getTeamId())
                    .orElseThrow(() -> new RuntimeException("团队不存在"));
            
            // 获取队员信息
            List<TeamMember> members = teamMemberRepository.findByTeamId(team.getId());
            
            // 生成自动文件名：题目名称_队员1_队员2_队员3_队伍编号.pdf
            String autoFileName = generateAutoFileName(topic, members, team);
            
            // 创建目录
            String thesisDir = uploadPath + "thesis/";
            String supportDir = uploadPath + "support/";
            
            File thesisDirFile = new File(thesisDir);
            File supportDirFile = new File(supportDir);
            
            if (!thesisDirFile.exists()) {
                thesisDirFile.mkdirs();
            }
            if (!supportDirFile.exists()) {
                supportDirFile.mkdirs();
            }
            
            // 保存论文文件
            String thesisPath = thesisDir + autoFileName + ".pdf";
            File thesisFile = new File(thesisPath);
            thesis.transferTo(thesisFile);
            
            // 保存支撑材料
            String supportPath = supportDir + autoFileName + ".rar";
            File supportFile = new File(supportPath);
            support.transferTo(supportFile);
            
            // 保存作品信息到数据库
            Work work = new Work();
            work.setId(UUID.randomUUID().toString());
            work.setTeamId(team.getId());
            work.setContestId(contestId);
            work.setTopicId(topicId);
            work.setThesisPath(thesisPath);
            work.setSupportPath(supportPath);
            work.setAutoName(autoFileName + ".pdf");
            
            workRepository.save(work);
            
            UploadResponse response = new UploadResponse();
            response.setWorkId(work.getId());
            response.setThesisName(autoFileName + ".pdf");
            
            return ApiResponse.success("上传成功", response);
            
        } catch (Exception e) {
            return ApiResponse.error(500, "作品上传失败: " + e.getMessage());
        }
    }
    
    /**
     * 生成自动文件名：题目名称_队员1_队员2_队员3_队伍编号.pdf
     */
    private String generateAutoFileName(Topic topic, List<TeamMember> members, Team team) {
        StringBuilder fileName = new StringBuilder();
        
        // 添加题目名称
        fileName.append(topic.getName());
        
        // 添加队员姓名
        for (TeamMember member : members) {
            fileName.append("_").append(member.getName());
        }
        
        // 添加队伍编号
        fileName.append("_").append(team.getId());
        
        return fileName.toString();
    }
    
    // 请求和响应类
    public static class RegisterRequest {
        private CaptainRequest captain;
        private String teamName;
        private List<MemberRequest> members;
        
        // Getters and Setters
        public CaptainRequest getCaptain() { return captain; }
        public void setCaptain(CaptainRequest captain) { this.captain = captain; }
        
        public String getTeamName() { return teamName; }
        public void setTeamName(String teamName) { this.teamName = teamName; }
        
        public List<MemberRequest> getMembers() { return members; }
        public void setMembers(List<MemberRequest> members) { this.members = members; }
    }
    
    public static class CaptainRequest {
        private String username;
        private String password;
        private String name;
        private String studentId;
        private String phone;
        
        // Getters and Setters
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        
        public String getStudentId() { return studentId; }
        public void setStudentId(String studentId) { this.studentId = studentId; }
        
        public String getPhone() { return phone; }
        public void setPhone(String phone) { this.phone = phone; }
    }
    
    public static class MemberRequest {
        private String name;
        private String studentId;
        private String phone;
        
        // Getters and Setters
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        
        public String getStudentId() { return studentId; }
        public void setStudentId(String studentId) { this.studentId = studentId; }
        
        public String getPhone() { return phone; }
        public void setPhone(String phone) { this.phone = phone; }
    }
    
    public static class RegisterResponse {
        private String teamId;
        private String username;
        
        // Getters and Setters
        public String getTeamId() { return teamId; }
        public void setTeamId(String teamId) { this.teamId = teamId; }
        
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
    }
    
    public static class UploadResponse {
        private String workId;
        private String thesisName;
        
        // Getters and Setters
        public String getWorkId() { return workId; }
        public void setWorkId(String workId) { this.workId = workId; }
        
        public String getThesisName() { return thesisName; }
        public void setThesisName(String thesisName) { this.thesisName = thesisName; }
    }
} 